package com.nCovInfo.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.nCovInfo.pojo.User;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.RandomAccessFile;

public class CommonUtils {
	/*
	 * 加密用的Key 可以用26个字母和数字组成 使用AES-128-CBC加密模式，key需要为16位。
	 */
	private static final String key = "hj7x89H$yuBI0456";
	private static final String iv = "NIfb&95GUY86Gfgh";
	/**
	 * @author miracle.qu
	 * @Description AES算法加密明文
	 * @param data 明文
	 * @return 密文
	 */
	public static String encryptAES(String data){
		try {
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			int blockSize = cipher.getBlockSize();
			byte[] dataBytes = data.getBytes();
			int plaintextLength = dataBytes.length;

			if (plaintextLength % blockSize != 0) {
				plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
			}

			byte[] plaintext = new byte[plaintextLength];
			System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

			SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
			IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());  // CBC模式，需要一个向量iv，可增加加密算法的强度

			cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
			byte[] encrypted = cipher.doFinal(plaintext);

			return CommonUtils.encode(encrypted).trim(); // BASE64做转码。

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * @author miracle.qu
	 * @Description AES算法解密密文
	 * @param data 密文
	 * @return 明文
	 */
	public static String decryptAES(String data) throws Exception {
		if(StringUtils.isBlank(data))return "";
		try
		{
			//先用base64解密
			byte[] encrypted1 = CommonUtils.decode(data);
			Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
			SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
			IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
			cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
			byte[] original = cipher.doFinal(encrypted1);
			String originalString = new String(original);
			return originalString.trim();
		}
		catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	/**
	 * 编码
	 * @param byteArray
	 * @return
	 */
	private static String encode(byte[] byteArray) {
		return new String(new Base64().encode(byteArray));
	}

	/**
	 * 解码
	 * @param base64EncodedString
	 * @return
	 */
	private static byte[] decode(String base64EncodedString) {
		return new Base64().decode(base64EncodedString);
	}


	private static final String USER_JSON = "user.json";
	public static JSONArray getUserList(boolean isEncoding) {
		String user = "[]";
		try {
			String userPath = Thread.currentThread().getContextClassLoader().getResource(USER_JSON).getPath();
			user = FileUtil.readLine(new RandomAccessFile(userPath, "r"), CharsetUtil.CHARSET_UTF_8);
		} catch (Exception e) {
			return new JSONArray();
		}
		JSONArray array = JSON.parseArray(user);
		if (isEncoding) {
			JSONArray enArray = new JSONArray();
			array.stream().forEach(json -> {
				User u = JSONObject.parseObject(json.toString(),User.class);
				try {
					u.setIdCardNum(CommonUtils.decryptAES(u.getIdCardNum()));
					u.setTelNum(CommonUtils.decryptAES(u.getTelNum()));
				} catch (Exception e) {
					e.printStackTrace();
				}
				enArray.add(u);
			});
			return enArray;
		}else{
			return array;
		}
	}

	/**
	 * 持久化
	 * @param array
	 * @throws Exception
	 */
	public static void writeFile(JSONArray array)throws Exception{
		FileWriter writer = new FileWriter(CommonUtils.class.getClassLoader()
				.getResource("").getPath() + "user.json",false);
		writer.write(JSON.toJSONString(array));
		writer.flush();
	}

}
